package info.niwota.group.thread;

import info.niwota.group.Constants;
import info.niwota.group.EtalkIntent;
import info.niwota.group.R;
import info.niwota.group.RecipientsActivity;
import info.niwota.group.Utils;
import info.niwota.group.thread.Topic.Threads;
import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

public class EditTopicActivity extends Activity implements TextWatcher,
		OnClickListener {
	private static final String TAG = "EditTopicActivity";

	private final static int RC_RECIPIENT_SELECT = 1;

	private Button btnDiscard;

	private Button btnSave;

	private boolean canBack = true;

	private EditText editBody;

	private EditText editSubject;

	private EditText editName;

	private EditText editRecipient;

	private TextView viewName;

	private boolean update;

	private int id = -1;

	public void afterTextChanged(Editable s) {

	}

	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
	}

	private String getString(Bundle icicle, String key) {
		return (icicle == null ? null : icicle.getString(key));
	}

	private String getString(EditText edit) {
		return (edit == null ? null : edit.getText().toString());
	}

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		//
		requestWindowFeature(Window.FEATURE_LEFT_ICON);
		setContentView(R.layout.topic_edit);

		viewName = (TextView) findViewById(R.id.topic_view_name);
		editName = (EditText) findViewById(R.id.topic_edit_name);
		editSubject = (EditText) findViewById(R.id.topic_edit_subject);
		editRecipient = (EditText) findViewById(R.id.topic_edit_recipient);
		editBody = (EditText) findViewById(R.id.topic_edit_body);

		//
		setTitle(R.string.title_topic_edit);
		getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
				R.drawable.icon25);
		//
		String name = null;
		String title = null;
		String body = null;
		String emails = null;

		if (icicle != null) {
			name = getString(icicle, Topic.EXTRA_NAME);
			title = getString(icicle, Topic.EXTRA_TITLE);
			body = getString(icicle, Topic.EXTRA_BODY);
			emails = getString(icicle, Topic.EXTRA_EMAILS);
			//
			update = icicle.getBoolean(Intent.ACTION_EDIT, false);
			id = icicle.getInt(Topic.EXTRA_ID);
		} else {
			String act = getIntent().getAction();
			update = (act == null ? false : act.equals(Intent.ACTION_EDIT));
			Bundle extras = getIntent().getExtras();
			if (extras != null) {
				id = extras.getInt(Topic.EXTRA_ID);
				//
				name = getString(extras, Topic.EXTRA_NAME);
				title = getString(extras, Topic.EXTRA_TITLE);
				body = getString(extras, Topic.EXTRA_BODY);
				emails = getString(extras, Topic.EXTRA_EMAILS);
			}
		}
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "update: " + update + " id: " + id);
		}
		viewName.setText(name);
		editName.setText(name);
		if (update) {
			viewName.setVisibility(View.VISIBLE);
			editName.setVisibility(View.GONE);
		} else {
			viewName.setVisibility(View.GONE);
			editName.setVisibility(View.VISIBLE);
		}
		editSubject.setText(title);
		editRecipient.setText(emails);
		editBody.setText(body);

		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "name: " + name);
		}
		//
		final ImageButton addrBtn = (ImageButton) findViewById(R.id.topic_edit_recipient_select);
		addrBtn.setOnClickListener(this);
		addrBtn.setVisibility(View.VISIBLE);
		//
		btnSave = (Button) findViewById(R.id.topic_edit_save);
		btnSave.setOnClickListener(this);

		btnDiscard = (Button) findViewById(R.id.topic_edit_discard);
		btnDiscard.setOnClickListener(this);

		btnSave.setEnabled(false);
		btnDiscard.setEnabled(true);

		editName.addTextChangedListener(this);
		editSubject.addTextChangedListener(this);
		editRecipient.addTextChangedListener(this);
		editBody.addTextChangedListener(this);
		//
		canBack = true;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			if (canBack) {
				setResult(RESULT_CANCELED);
				finish();
			}
			return true;
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putString(Topic.EXTRA_NAME, Utils
				.normalize(getString(editName)));
		outState.putString(Topic.EXTRA_TITLE, getString(editSubject));
		outState.putString(Topic.EXTRA_BODY, getString(editBody));
		outState.putString(Topic.EXTRA_EMAILS, getString(editRecipient));

		//
		outState.putInt(Topic.EXTRA_ID, id);
		outState.putBoolean(Intent.ACTION_EDIT, update);
	}

	public void onTextChanged(CharSequence s, int start, int before, int count) {
		// name is required, at least one non space character
		boolean save = false;
		int len = editName.length();
		if (len > 0) {
			Editable et = editName.getText();
			for (int i = 0; i < len; i++) {
				if (!Character.isSpaceChar(et.charAt(i))) {
					save = true;
					break;
				}
			}
		}
		btnSave.setEnabled(save);
		canBack = !save;
	}

	@Override
	protected void onActivityResult(int rc, int resultCode, Intent data) {
		if (resultCode == RESULT_OK) {
			switch (rc) {
			case RC_RECIPIENT_SELECT: {
				String emails = null;
				String list = null;
				if (data != null) {
					Bundle extras = data.getExtras();
					if (extras != null) {
						emails = extras.getString(EtalkIntent.EXTRA_EMAILS);
						list = extras.getString(EtalkIntent.EXTRA_LISTNAME);
						//
						if (Constants.DEBUG_ENABLED) {
							Log.d(TAG, "new list name: " + list);
						}
					}
				}
				//
				updateRecipients(emails);
				break;
			}
			default:
			}
		}
	}

	private void updateRecipients(String emails) {
		String tos = (isSelf(emails) ? "" : emails);
		//
		String old = editRecipient.getText().toString();
		String s = cat(old, tos, ",");
		s = parseEmail(s);
		editRecipient.setText(s);
		//
		editRecipient.requestFocus();
	}

	private String cat(String s1, String s2, String delimit) {
		if (TextUtils.isEmpty(s1)) {
			return s2;
		}
		if (TextUtils.isEmpty(s2)) {
			return s1;
		}
		return (s1 + delimit + s2);
	}

	private String parseEmail(String to) {
		if (!TextUtils.isEmpty(to)) {
			to = Utils.toString(Utils.parseEmail(to));
		}
		return to;
	}

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.topic_edit_recipient_select:
			doRecipientSelect();
			return;
		case R.id.topic_edit_save:
			doSave();
			break;
		case R.id.topic_edit_discard: {
			setResult(RESULT_CANCELED);
			finish();
			break;
		}
		default:
		}
	}

	private void doRecipientSelect() {
		startRecipientsActivity();
	}

	private void startRecipientsActivity() {
		Intent i = new Intent(this, RecipientsActivity.class);
		// String listname = "";
		// String emails = editRecipient.getText().toString();
		// if (!isSelf(emails)) {
		// i.putExtra(EtalkIntent.EXTRA_EMAILS, emails);
		// }
		// clear selection
		i.putExtra(EtalkIntent.EXTRA_EMAILS, "");
		i.putExtra(EtalkIntent.EXTRA_LISTNAME, "");

		startActivityForResult(i, RC_RECIPIENT_SELECT);
	}

	private static boolean isSelf(String s) {
		//
		return (s == null || s.equals("") || s.equals("<self>"));
	}

	private String getString(Intent data, String key, String def) {
		if (data == null) {
			return def;
		}
		String s = data.getStringExtra(key);
		return (s == null ? def : s);
	}

	private boolean updateThread(Intent data) {
		Uri topicUri = ContentUris.withAppendedId(Topic.ALL_TOPICS_URI, id);
		ContentValues values = prepareValues(data);
		int rc = getContentResolver().update(topicUri, values, "_id = " + id,
				null);
		if (rc > 0) {
			Toast.makeText(this, R.string.msg_topic_edit, Toast.LENGTH_SHORT)
					.show();
			return true;
		}
		//
		Toast.makeText(this, getString(R.string.msg_topic_failed, id),
				Toast.LENGTH_SHORT).show();
		return false;
	}

	private boolean addThread(Intent data) {
		ContentValues values = prepareValues(data);
		String name = data.getStringExtra(Topic.EXTRA_NAME);
		Uri topicUri = Uri.withAppendedPath(Topic.ALL_TOPICS_URI, name);
		Uri uri = getContentResolver().insert(topicUri, values);
		if (uri != null) {
			if (Constants.DEBUG_ENABLED) {
				long id = Long.parseLong(uri.getLastPathSegment());
				Log.d(TAG, "row Id:  " + id + " uri: " + uri);
			}
			Toast.makeText(this, R.string.msg_topic_add, Toast.LENGTH_SHORT)
					.show();
			return true;
		}
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "Failed to insert " + data);
		}
		Toast.makeText(this, getString(R.string.msg_topic_failed, name),
				Toast.LENGTH_SHORT).show();
		return false;
	}

	private ContentValues prepareValues(Intent data) {
		String name = data.getStringExtra(Topic.EXTRA_NAME);
		ContentValues values = new ContentValues();
		Long now = System.currentTimeMillis();
		values.put(Threads.NAME, name);
		values.put(Threads.TITLE, getString(data, Topic.EXTRA_TITLE, ""));
		values.put(Threads.BODY, getString(data, Topic.EXTRA_BODY, ""));
		values.put(Threads.EMAILS, getString(data, Topic.EXTRA_EMAILS, ""));
		values.put(Threads.CREATED_DATE, now);
		values.put(Threads.MODIFIED_DATE, now);
		return values;
	}

	private void doSave() {
		Intent i = new Intent();
		String name = Utils.normalize(getString(editName));
		i.putExtra(Topic.EXTRA_NAME, name);
		i.putExtra(Topic.EXTRA_TITLE, getString(editSubject));
		i.putExtra(Topic.EXTRA_BODY, getString(editBody));
		i.putExtra(Topic.EXTRA_EMAILS, getString(editRecipient));
		try {
			if (saveThread(i)) {
				setResult(RESULT_OK, i);
				finish();
			}
		} catch (Exception e) {
			e.printStackTrace();
			//
			Toast.makeText(this,
					getString(R.string.msg_topic_failed, e.getMessage()),
					Toast.LENGTH_SHORT).show();
		}
	}

	private boolean saveThread(Intent data) {
		if (update) {
			return updateThread(data);
		} else {
			return addThread(data);
		}
	}
}
